// Client.cpp
// Cours CORBA
// Cours 1, Exemple 1

#include <fstream>
#include <iostream>
#include <sstream>
#include "Dictionnary.hh"	// généré par omniidl

using namespace std;
using namespace Dict;

//extern ostream cerr;
//extern ostream cout;


static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb);
/*static void echo(HelloWorld_ptr e)
{
  CORBA::String_var src = (const char*) "Hello (from Landry)!";

  CORBA::String_var dest = e->echo(src);

  cout << "I said, \"" << (char*)src << "\"." << endl
       << "The Echo object replied, \"" << (char*)dest <<"\"." << endl;
}
*/


int	main(int argc, char **argv) 
{
	
	try{
		CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
		//CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv, "omniORB4");
    		CORBA::Object_var obj = getObjectReference(orb);
		Dictionnary_var helloRef = Dictionnary::_narrow(obj);


		/*HelloWorld_var helloRef = HelloWorld::_narrow(obj);
		CORBA::Object_var objRef = orb->string_to_object(ref);
		HelloWorld_var helloRef = HelloWorld::_narrow(objRef);

		for (CORBA::ULong count=0; count < 10; count++){
      			echo(helloRef);
		}

		helloRef->hello(argv[1]);*/

		//int i = helloRef->loadDict();	

		//char *ent = (*(helloRef->firstEntity())).myDefinition();
		cout <<endl;
		cout << "I said, \"" << "The Echo object replied, \"" << helloRef->loadDict() <<"\"." << endl;

		cout << "first word  : " << ((*(helloRef->firstEntity())).myEntry())->myTerm() <<endl;
		
		cout << "next word  : " << ((*(helloRef->nextEntity())).myEntry())->myTerm() <<endl;

		cout << "last word  : " << ((*(helloRef->lastEntity())).myEntry())->myTerm() <<endl;
	
		helloRef->sortDict(true);
		
		cout << "Sorting the dictionary : ascending"<<endl;

		cout << "first word  : " << ((*(helloRef->firstEntity())).myEntry())->myTerm() <<endl;
		
		//cout << "find entity word  : " << ((*(helloRef->findEntity(CORBA::string_dup("Landry")))).myEntry())->myTerm() <<endl;

		cout << "last word  : " << ((*(helloRef->lastEntity())).myEntry())->myTerm() <<endl;


		cout << "Sorting the dictionary : decroissant"<<endl;
		helloRef->sortDict(false);
		
		//helloRef->modifDefinition(CORBA::string_dup("Landry"), CORBA::string_dup("Nouvelle de finition de homme"));

		cout << "first word  : " << ((*(helloRef->firstEntity())).myEntry())->myTerm() <<endl;
		
		cout << "next word  : " << ((*(helloRef->nextEntity())).myEntry())->myTerm() <<endl;

		cout << "last word  : " << ((*(helloRef->lastEntity())).myEntry())->myTerm() <<endl;

		//cout << "Definition is : " << (*(helloRef->firstEntity())).myDefinition() <<endl;
		cout <<endl;

		cout << " Liste definition"<<endl;
		
		cout << "Et la Definition du first : " << (*(helloRef->firstEntity())).myDefinition() <<endl;	
		//cout <<endl;

		cout << "Et la Definition du next : " << (*(helloRef->nextEntity())).myDefinition() <<endl;	

		cout << "Et la Definition du next : " << (*(helloRef->nextEntity())).myDefinition() <<endl;	

		//cout << "Et la Definition du next : " << (*(helloRef->nextEntity())).myDefinition() <<endl;

		//cout << "Et la Definition du next : " << (*(helloRef->nextEntity())).myDefinition() <<endl;	

		CategoryValue cat = VER;
		PropertyType props;
		
		PropNom pn;		
		pn.genre = MASC;
		pn.pluriel = CORBA::string_dup("Action de pluriels ");
		//PropVer pv;
		//pv.groupe = G2;
		//pv.transitivite = TRANS;	
		props.pNom(pn);		

		helloRef->addEntity(CORBA::string_dup("bonjour"),cat, props, CORBA::string_dup("Action de tester la qualite d'un element ou d'une chose"));	
		
		//pv.groupe = G1;
		//props.pVer(pv);				
	
		//helloRef->addEntity(CORBA::string_dup("Laver"),cat, props, CORBA::string_dup("Action de laver"));	
		//pv.groupe = G1;
		//pv.transitivite = INTR;
		//props.pVer(pv);			

		//helloRef->addEntity(CORBA::string_dup("Nager"),cat, props, CORBA::string_dup("Action de nager dans l'eau sale"));	

		//cout << "find entity word  : " << ((*(helloRef->findEntity(CORBA::string_dup("Nager")))).myEntry())->myTerm() <<endl;

		//helloRef->delEntity (CORBA::string_dup("tester"));		

		/*cout << "Et la Definition du last : " << (*(helloRef->lastEntity())).myDefinition() <<endl;	
		cout <<endl;
		cout << "Et la Definition du prev : " << (*(helloRef->prevEntity())).myDefinition() <<endl;
		cout <<endl;
		cout << "Et la Definition du prev : " << (*(helloRef->prevEntity())).myDefinition() <<endl;	

		cout <<endl;
		cout << "Et la Definition du prev : " << (*(helloRef->prevEntity())).myDefinition() <<endl;	*/
		//helloRef->dictLength();
		helloRef->saveDict();
		cout << "Taille du Dico : " << helloRef->dictLength() << endl;		
		
    		orb->destroy();
	}
	// On initialise l'ORB
	//CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv, "omniORB4");

	// On récupère l'IOR de l’objet distant
	//char	ref[1000];
		
	// On ouvre le fichier contenant l'IOR
	//ifstream	in("hello.ior");
	
	//ifstream in(argv[1]);

	// On lit l'IOR
	//in >> ref;

	// On convertit l'IOR en référence objet
	//CORBA::Object_var objRef = orb->string_to_object(ref);

	// On caste cette référence vers une référence de type "HelloWorld"
	//HelloWorld_var helloRef = HelloWorld::_narrow(objRef);

	// On appelle la méthode de l'objet distant
	//helloRef->hello(argv[2]);
	catch(CORBA::TRANSIENT&) {
    		cerr << "Caught system exception TRANSIENT -- unable to contact the "
        	<< "server." << endl;
  	}
  	catch(CORBA::SystemException& ex) {
    		cerr << "Caught a CORBA::" << ex._name() << endl;
  	}
  	catch(CORBA::Exception& ex) {
    		cout << "Caught CORBA::Exception: " << ex._name() << endl;
  	}
  	catch(omniORB::fatalException& fe) {
    		cerr << "Caught omniORB::fatalException:" << endl;
    		cerr << " file: " << fe.file() << endl;
    		cerr << " line: " << fe.line() << endl;
    		cerr << " mesg: " << fe.errmsg() << endl;
  	}
	return 0;
}


//////////////////////////////////////////////////////////////////////
static CORBA::Object_ptr
getObjectReference(CORBA::ORB_ptr orb)
{
  CosNaming::NamingContext_var rootContext;
  try {
    // Obtain a reference to the root context of the Name service:
    CORBA::Object_var obj;
    obj = orb->resolve_initial_references("NameService");
    // Narrow the reference returned.
    rootContext = CosNaming::NamingContext::_narrow(obj);
  if( CORBA::is_nil(rootContext) ) {
    cerr << "Failed to narrow the root naming context." << endl;
    return CORBA::Object::_nil();
  }
}
catch (CORBA::NO_RESOURCES&) {
  cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
       << "with the location" << endl
       << "of the naming service." << endl;
  return 0;
}
catch(CORBA::ORB::InvalidName& ex) {
  // This should not happen!
  cerr << "Service required is invalid [does not exist]." << endl;
  return CORBA::Object::_nil();
}
// Create a name object, containing the name test/context:
CosNaming::Name name;
name.length(2);
name[0].id   = (const char*) "Dictionnary";       // string copied
name[0].kind = (const char*) "dictionnary_context"; // string copied
name[1].id   = (const char*) "Dictionnary";
name[1].kind = (const char*) "Object";
// Note on kind: The kind field is used to indicate the type
// of the object. This is to avoid conventions such as that used
// by files (name.type -- e.g. test.ps = postscript etc.)
try {
  // Resolve the name to an object reference.
  return rootContext->resolve(name);
}
catch(CosNaming::NamingContext::NotFound& ex) {
  // This exception is thrown if any of the components of the
  // path [contexts or the object] aren’t found:
  cerr << "Context not found." << endl;
}
catch(CORBA::TRANSIENT& ex) {
  cerr << "Caught system exception TRANSIENT -- unable to contact the "
       << "naming service." << endl
       << "Make sure the naming server is running and that omniORB is "
       << "configured correctly." << endl;
}
catch(CORBA::SystemException& ex) {
  cerr << "Caught a CORBA::" << ex._name()
       << " while using the naming service." << endl;
  return 0;
  }
  return CORBA::Object::_nil();
}

